package com.zgjkhis.modules.system.rest;

import cn.hutool.poi.excel.ExcelFileUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zgjkhis.domain.PageResult;
import com.zgjkhis.dozer.service.IGenerator;
import com.zgjkhis.exception.ServiceException;
import com.zgjkhis.logging.aop.log.Log;
import com.zgjkhis.modules.group.DrugNoGroup;
import com.zgjkhis.modules.group.DrugSalePriceGroup;
import com.zgjkhis.modules.group.DrugStatusGroup;
import com.zgjkhis.modules.group.DrugWarnNumGroup;
import com.zgjkhis.modules.security.security.LoginUserUtil;
import com.zgjkhis.modules.system.domain.Dict;
import com.zgjkhis.modules.system.domain.DictDetail;
import com.zgjkhis.modules.system.domain.Drug;
import com.zgjkhis.modules.system.domain.DrugWareHousingDetail;
import com.zgjkhis.modules.system.domain.vo.DrugBatchVO;
import com.zgjkhis.modules.system.domain.vo.DrugSaleVo;
import com.zgjkhis.modules.system.domain.vo.DrugWareHousingDetailUpdate;
import com.zgjkhis.modules.system.service.*;
import com.zgjkhis.modules.system.service.dto.DrugQueryCriteria;
import com.zgjkhis.modules.system.service.dto.DrugWareHousingDetailDto;
import com.zgjkhis.modules.util.CharUtil;
import com.zgjkhis.modules.util.PingYinUtil;
import com.zgjkhis.modules.valid.ValidList;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Set;

/**
 * @date 2018-11-23
 */
@Api(tags = "库房管理：药品管理")
@RestController
@RequestMapping("/drug")
public class DrugController {

    private static final String ENTITY_NAME = "durg";
    private final DrugService drugService;
    private final IGenerator generator;
    private final DictService dictService;
    private final DictDetailService dictDetailService;
    private final DrugWareHousingDetailService drugWareHousingDetailService;
    private final InfoDrugService infoDrugService;

    public DrugController(DrugService drugService, IGenerator generator, DictService dictService, DictDetailService dictDetailService, DrugWareHousingDetailService drugWareHousingDetailService, InfoDrugService infoDrugService) {
        this.drugService = drugService;
        this.generator = generator;
        this.dictService = dictService;
        this.dictDetailService = dictDetailService;
        this.drugWareHousingDetailService = drugWareHousingDetailService;
        this.infoDrugService = infoDrugService;
    }

    @Log("查看单个药品详情")
    @GetMapping(value = "/detail")
    @ApiOperation("查询单个药品详情")
    //    @PreAuthorize("@el.check('drug:datail')")
    public ResponseEntity<Object> getDetail(String id) {
        if (CharUtil.isEmpty(id)) {
            throw new ServiceException("id不能为空");
        }
        return new ResponseEntity<>(drugService.findDetailById(id), HttpStatus.OK);
    }

    @Log("查看药品批次详情")
    @GetMapping(value = "/getDetails")
    @ApiOperation("查看药品批次详情")
    //    @PreAuthorize("@el.check('drug:datail')")
    public ResponseEntity<PageResult<DrugWareHousingDetailDto>> getDetails(String id, String startDate, String endDate, String type, String supplierId, Pageable pageable) {
        if (CharUtil.isEmpty(id)) {
            throw new ServiceException("id不能为空");
        }
        DrugQueryCriteria criteria = new DrugQueryCriteria();
        criteria.setDrugId(id);
        criteria.setPharmacyId(LoginUserUtil.getPharmId());
        criteria.setStartDate(startDate);
        criteria.setEndDate(endDate);
        criteria.setType(type);
        criteria.setSupplierId(supplierId);
        return new ResponseEntity<>(drugWareHousingDetailService.findAllByPageable(criteria, pageable), HttpStatus.OK);
    }


    @Log("新增药品")
    @ApiOperation("新增药品")
    @PostMapping(value = "/add")
//    @PreAuthorize("@el.check('drug:add')")
    public ResponseEntity<Object> create(@Validated @RequestBody Drug resources) {
        if (resources.getId() != null) {
            throw new ServiceException("A new " + ENTITY_NAME + " cannot already have an ID");
        }
        resources.setPinyin(PingYinUtil.getFirstSpell(resources.getDrugName()));
        return new ResponseEntity<>(drugService.save(resources), HttpStatus.OK);
    }

    @Log("批量新增药品")
    @ApiOperation("批量新增药品")
    @PostMapping(value = "/addList")
//    @PreAuthorize("@el.check('drug:add')")
    public ResponseEntity<Object> createList(@Validated @RequestBody ValidList<Drug> resources) {
        resources.forEach(drug -> {
            drug.setPinyin(PingYinUtil.getFirstSpell(drug.getDrugName()));
            drug.setPharmacyId(LoginUserUtil.getPharmId());
        });
        boolean b = drugService.saveBatch(resources);
        return new ResponseEntity<>(b, HttpStatus.OK);
    }

    @Log("修改药品")
    @ApiOperation("修改药品")
    @PostMapping(value = "/update")
//    @PreAuthorize("@el.check('drug:edit')")
    public ResponseEntity<Object> update(@Validated @RequestBody Drug resources) {
        drugService.saveOrUpdate(resources);
        return ResponseEntity.ok(true);
    }

    @Log("修改药品状态")
    @ApiOperation("修改药品状态")
    @PostMapping(value = "/updateStatus")
//    @PreAuthorize("@el.check('drug:edit')")
    public ResponseEntity<Object> updateStatus(@Validated(DrugStatusGroup.class) @RequestBody DrugBatchVO drugBatchVO) {
        Drug drug = new Drug();
        drug.setId(drugBatchVO.getId());
        drug.setStatus(drugBatchVO.getStatus());
        drugService.saveOrUpdate(drug);
        return ResponseEntity.ok(true);
    }

    @Log("修改药品库位号")
    @ApiOperation("修改药品库位号")
    @PostMapping(value = "/updateDrugNo")
//    @PreAuthorize("@el.check('drug:edit')")
    public ResponseEntity<Object> updateDrugNo(@Validated(DrugNoGroup.class) @RequestBody DrugBatchVO drugBatchVO) {
        Drug drug = new Drug();
        drug.setId(drugBatchVO.getId());
        drug.setDrugNo(drugBatchVO.getDrugNo());
        drugService.saveOrUpdate(drug);
        return ResponseEntity.ok(true);
    }

    @Log("修改药品价格")
    @ApiOperation("修改药品价格")
    @PostMapping(value = "/updatePrice")
//    @PreAuthorize("@el.check('drug:edit')")
    public ResponseEntity<Object> updatePrice(@Validated(DrugSalePriceGroup.class) @RequestBody DrugBatchVO drugBatchVO) {
        Drug drug = new Drug();
        drug.setId(drugBatchVO.getId());
        drug.setSalePrice(drugBatchVO.getSalePrice());
        drugService.saveOrUpdate(drug);
        return ResponseEntity.ok(true);
    }

    @Log("修改入库批次药品")
    @ApiOperation("修改入库批次药品")
    @PostMapping(value = "/updateDrugDetail")
//    @PreAuthorize("@el.check('drug:edit')")
    public ResponseEntity<Object> updateDrugDetail(@Validated @RequestBody DrugWareHousingDetailUpdate resources) {
        DrugWareHousingDetail detail = new DrugWareHousingDetail();
        detail.setId(resources.getId());
        detail.setCostPrice(resources.getCostPrice());
        detail.setTermOfValidity(resources.getTermOfValidity());
        detail.setBatchNo(resources.getBatchNo());
        drugWareHousingDetailService.updateById(detail);
        return ResponseEntity.ok(true);
    }

    @Log("分页查询药品")
    @ApiOperation("分页查询药品")
    @GetMapping(value = "/getDrugs")
//    @PreAuthorize("@el.check('drug:list')")
    public ResponseEntity<PageResult<Drug>> getDrugs(DrugQueryCriteria criteria, Pageable pageable) {
        criteria.setPharmacyId(LoginUserUtil.getPharmId());
        return new ResponseEntity<>(drugService.findAllByPageable(criteria, pageable), HttpStatus.OK);
    }

    @Log("查询药品分类详情数量")
    @ApiOperation("查询药品分类详情数量")
    @GetMapping(value = "/getCountByDrugType")
//    @PreAuthorize("@el.check('drug:list')")
    public ResponseEntity<Object> getCountByDrugType(DrugQueryCriteria criteria) {
        criteria.setPharmacyId(LoginUserUtil.getPharmId());
        return new ResponseEntity<>(drugService.findCountByDrugType(criteria), HttpStatus.OK);
    }

    @Log("批量修改药品预警值")
    @ApiOperation("批量修改药品预警值")
    @PostMapping(value = "/batchUpdateWarning")
//    @PreAuthorize("@el.check('drug:list')")
    public ResponseEntity<Object> batchUpdateWarning(@Validated(DrugWarnNumGroup.class) @RequestBody ValidList<DrugBatchVO> drugBatchVO) {
        return new ResponseEntity<>(drugService.batchUpdateWarning(drugBatchVO), HttpStatus.OK);
    }

    @Log("批量修改药品状态")
    @ApiOperation("批量修改药品状态")
    @PostMapping(value = "/batchUpdateStatus")
//    @PreAuthorize("@el.check('drug:list')")
    public ResponseEntity<Object> batchUpdateStatus(@Validated(DrugStatusGroup.class) @RequestBody ValidList<DrugBatchVO> drugBatchVO) {
        return new ResponseEntity<>(drugService.batchUpdateStatus(drugBatchVO), HttpStatus.OK);
    }

    @Log("获取药品分类")
    @ApiOperation("获取药品分类")
    @PostMapping(value = "/getDrugTypes")
//    @PreAuthorize("@el.check('drug:list')")
    public ResponseEntity<Object> getDrugTypes() {
        Dict dict = dictService.getOne(Wrappers.<Dict>query().lambda().eq(Dict::getName, "drug_type"));
        List<DictDetail> list = dictDetailService.list(Wrappers.<DictDetail>query().lambda().eq(DictDetail::getDictId, dict.getId()));
        return new ResponseEntity<>(list, HttpStatus.OK);
    }

    @Log("根据药品分类下载药品")
    @ApiOperation("根据药品分类下载药品")
    @PostMapping(value = "/downloadDrugByType")
//    @PreAuthorize("@el.check('drug:list')")
    public void downloadDrugByType(HttpServletResponse response, @RequestBody Set<Long> drugTypes) throws IOException {
        String pharmacyId = LoginUserUtil.getPharmId();
        List<Drug> list = drugService.list(Wrappers.<Drug>query().lambda().in(Drug::getDrugType, drugTypes).eq(Drug::getPharmacyId, pharmacyId));
        drugService.dowonload(list, response);
    }

    @Log("批量修改药品价格")
    @ApiOperation("批量修改药品价格")
    @PostMapping(value = "/batchUpdateSalePrice")
//    @PreAuthorize("@el.check('drug:list')")
    public ResponseEntity<Object> batchUpdateSalePrice(@RequestParam("file") MultipartFile file) throws IOException {
        if (file == null) {
            throw new ServiceException("请上传文件");
        }
        if (!ExcelFileUtil.isXls(file.getInputStream()) && !ExcelFileUtil.isXlsx(file.getInputStream())) {
            throw new ServiceException("请上传excel文件");
        }
        drugService.batchUpdateSalsePrice(file);
        return new ResponseEntity<>(true, HttpStatus.OK);
    }

    @Log("批量导入药品")
    @ApiOperation("批量导入药品")
    @PostMapping(value = "/batchsave")
//    @PreAuthorize("@el.check('drug:list')")
    public ResponseEntity<Object> batchsave(@RequestParam("file") MultipartFile file, @ApiParam("上传类型：1：西药，中成药，2：中药饮片和配方颗粒，3：耗材") String flag) throws IOException {
        if (file == null) {
            throw new ServiceException("请上传文件");
        }
        if (!ExcelFileUtil.isXls(file.getInputStream()) && !ExcelFileUtil.isXlsx(file.getInputStream())) {
            throw new ServiceException("请上传excel文件");
        }
        drugService.batchSave(file, flag);
        return new ResponseEntity<>(true, HttpStatus.OK);
    }


    @Log("查看药品库存详情")
    @GetMapping(value = "/getStockDetails")
    @ApiOperation("查看药品库存详情")
    //    @PreAuthorize("@el.check('drug:datail')")
    public ResponseEntity<PageResult<DrugSaleVo>> getStockDetails(String drugId, String startDate, String endDate, String userName, String docName, String type, Pageable pageable) {
        if (CharUtil.isEmpty(drugId)) {
            throw new ServiceException("id不能为空");
        }
        String pharmacyId = LoginUserUtil.getPharmId();
        return new ResponseEntity<>(infoDrugService.drugStock(pharmacyId, drugId, startDate, endDate, userName, docName, type, pageable), HttpStatus.OK);

    }


    @Log("导出药品库存")
    @ApiOperation("导出药品库存")
    @GetMapping(value = "/outStockDetails")
    public void outStockDetails(String drugId, String startDate, String endDate, String userName, String docName, String type, HttpServletResponse response) throws IOException {
        String pharmacyId = LoginUserUtil.getPharmId();
        infoDrugService.outStockDetails(pharmacyId, drugId, startDate, endDate, userName, docName, type, response);
    }

    @Log("导出药品")
    @ApiOperation("导出药品")
    @GetMapping(value = "/outDrugs")
//    @PreAuthorize("@el.check('drug:list')")
    public void outDrugs(HttpServletResponse response, DrugQueryCriteria criteria) throws IOException {
        criteria.setPharmacyId(LoginUserUtil.getPharmId());
        drugService.outDrugs(criteria, response);
    }

    @Log("导出批次详情")
    @ApiOperation("导出药品库存")
    @GetMapping(value = "/outDetails")
    public void outDetails(String id, String startDate, String endDate, String type, String supplierId, Pageable pageable, HttpServletResponse response) throws IOException {
        DrugQueryCriteria criteria = new DrugQueryCriteria();
        criteria.setDrugId(id);
        criteria.setPharmacyId(LoginUserUtil.getPharmId());
        criteria.setStartDate(startDate);
        criteria.setEndDate(endDate);
        criteria.setType(type);
        criteria.setSupplierId(supplierId);
        drugWareHousingDetailService.outDetails(criteria, response);
    }


}
